#ifndef DOUBLEBF2_HPP
#define DOUBLEBF2_HPP

#include "doublebf.hpp"

template<typename T>
class DoubleBf2 : public DoubleBf<T>
{
    T *r;
    bool isEmpty;

public:
    DoubleBf2()
        : DoubleBf<T>()
        , r(NULL)
        , isEmpty(true)
    {

    }

    virtual ~DoubleBf2()
    {
        DoubleBf<T>::lock.lock();
        RR();
        DoubleBf<T>::lock.unlock();
        DoubleBf<T>::Release();
    }

    void RR()
    {
        if(r!=NULL)
        {
            delete r;
            r=NULL;
        }
    }

    void Write(T* &w0)
    {
        DoubleBf<T>::lock.lock();
//        std::cout<<"write\n"<<std::flush;
        RR();
        r=w0;
        isEmpty=false;
        DoubleBf<T>::lock.unlock();
    }

    bool TryRead(T* &r0)
    {
        DoubleBf<T>::lock.lock();
        //        std::cout<<"bf="<<DoubleBf<T>::bf.size()<<"\n"<<std::flush;
        if(isEmpty)
        {
//            std::cout<<"empty\n"<<std::flush;
            DoubleBf<T>::lock.unlock();
            return false;
        }
//        std::cout<<"full\n"<<std::flush;
        r0=r;
        r=NULL;
        isEmpty=true;
        DoubleBf<T>::lock.unlock();
        return true;

    }

    void Read(T* &r0)
    {
        while(!TryRead(r0))
        {
            std::this_thread::yield();
        }
    }


};


#endif // DOUBLEBF2_HPP

